<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col :span="6">
        <div class="head-container">
          <SaOrgTree @node-click="orgTreeNodeClick"/>
        </div>
      </el-col>
      <el-col :span="6">
        <div class="head-container">
          <el-input placeholder="输入权限项编码" v-model="itemQueryParams.code" size="small">
            <el-select v-model="itemQueryParams.defineId" slot="prepend" @change="handDefineChange" placeholder="请选择"
                       style="width:100px">
              <el-option v-for="item in defineList" :label="item.tableDesc" :value="item.id"></el-option>
            </el-select>
            <el-button-group slot="append">
              <el-button icon="el-icon-search" @click="handleQueryItemList" type="primary" size="small"></el-button>
            </el-button-group>
          </el-input>
        </div>
        <div class="head-container">
          <el-table :data="itemList"
                    border
                    highlight-current-row
                    @current-change="handleItemChange"
          >
            <!--            <el-table-column label="ID" align="center" prop="id"/>-->
            <!--      <el-table-column label="机构FULL_ID" align="center" prop="orgFullId" />-->
            <el-table-column label="编码" align="center" prop="code"/>
            <!--      <el-table-column label="权限项ID" align="center" prop="permissionItemId" />-->
            <el-table-column label="名称" align="center" prop="name"/>
          </el-table>
          <!-- 分页组件 -->
          <pagination v-show="itemTotal > itemQueryParams.pageSize" :total="itemTotal"
                      :page.sync="itemQueryParams.pageNo"
                      :limit.sync="itemQueryParams.pageSize" :pager-count="5" small
                      @pagination="handleQueryItemList"/>
        </div>

      </el-col>
      <el-col :span="12">
        <!-- 操作工具栏 -->
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
                       v-hasPermi="['sa:data-permission-config:create']">添加权限
            </el-button>
          </el-col>
          <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>

        <!-- 列表 -->
        <el-table v-loading="loading" :data="list">
          <el-table-column label="机构名称" align="left" prop="orgFullName" min-width="150" fixed show-overflow-tooltip>
            <template slot-scope="scope">
              <i v-show="currentOrgTreeData.fullId != scope.row.orgFullId" class="el-icon-lock"></i>
              <span style="margin-left: 10px">{{ scope.row.orgFullName }}</span>
            </template>
          </el-table-column>
          <el-table-column label="范围权限" align="left" prop="dataScope" min-width="150" show-overflow-tooltip>
            <template v-slot="scope">
              <dict-tag :type="DICT_TYPE.SA_DATA_SCOPE" :value="scope.row.dataScope"/>
            </template>
          </el-table-column>
          <el-table-column label="状态" align="center" prop="status">
            <template v-slot="scope">
              <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
            </template>
          </el-table-column>
          <el-table-column label="创建人" align="center" prop="creator"/>
          <el-table-column label="创建时间" align="center" prop="createTime" width="180">
            <template v-slot="scope">
              <span>{{ parseTime(scope.row.createTime) }}</span>
            </template>
          </el-table-column>
          <!--          <el-table-column label="更新人" align="center" prop="updater"/>-->
          <!--
                    <el-table-column label="更新时间" align="center" prop="updateTime" width="180">
                      <template v-slot="scope">
                        <span>{{ parseTime(scope.row.updateTime) }}</span>
                      </template>
                    </el-table-column>
                    -->
          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160px">
            <template v-slot="scope">
              <el-button size="mini" type="text" icon="el-icon-view" @click="handleReadonly(scope.row)">查看
              </el-button>
              <el-button size="mini" type="text" icon="el-icon-edit" @click="handleCreateExclude(scope.row)"
                         v-show="currentOrgTreeData.fullId != scope.row.orgFullId && !scope.row.excludeId"
                         v-hasPermi="['sa:data-permission-config:update']">排除
              </el-button>
              <el-button size="mini" type="text" icon="el-icon-edit" @click="handleDeleteExclude(scope.row)"
                         v-show="currentOrgTreeData.fullId != scope.row.orgFullId
                         && !!scope.row.excludeId
                         && currentOrgTreeData.fullId == scope.row.excludeOrgFullId"
                         v-hasPermi="['sa:data-permission-config:update']">不排除
              </el-button>
              <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
                         v-show="currentOrgTreeData.fullId == scope.row.orgFullId"
                         v-hasPermi="['sa:data-permission-config:update']">修改
              </el-button>
              <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
                         v-show="currentOrgTreeData.fullId == scope.row.orgFullId"
                         v-hasPermi="['sa:data-permission-config:delete']">删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页组件 -->
        <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
                    @pagination="getList"/>
      </el-col>
    </el-row>
    <!-- 对话框(添加 / 修改) -->
    <el-dialog :title="title" :visible.sync="open" width="550px" :disabled="readonly" v-dialogDrag append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="机构名称" prop="orgFullName">
          <el-input v-model="form.orgFullName" placeholder="请输入机构" disabled/>
        </el-form-item>
        <el-form-item label="权限项" prop="permissionItemCode">
          <el-input v-model="form.permissionItemCode" placeholder="请输入权限项编码" disabled/>
        </el-form-item>
        <el-form-item label="权限范围" prop="dataScope">
          <span slot="label">
                <el-tooltip content="" placement="top">
                   <div slot="content">
                     生成权限控制脚本时，使用IN或者LIKE语法<br/>
                     指定数据权限(不含下级)：保存数据权限时，保存每个选择项的ID，即使被选择数据是树结构，但保存后的数据没有树结构。生成脚本时使用IN关键字<br/>
                     指定数据权限（含下级）：保存数据权限时，保存每个选择项的全路径；当选择某个父节点数据时，那么会包含下级数据权限。保存数据时只保存范围更大的节点，如同时选中父节点和子节点，那么只会保存父节点。生成脚本时使用LIKE<br/>
                     指定数据权限（含下级）：可以解决新增子级数据时，不用再分配一次权限，而默认包含。<br/>
                     所属部门权限（限组织权限时可选）:后台根据用户所属部门，自动生成权限。<br/>
                     注：控制组织结构树的权限时要特别注意确保权限控制后还能保持树的结构。
                   </div>
                  <i class="el-icon-question"/>
                </el-tooltip>
                权限范围
              </span>
          <el-select v-model="form.dataScope" :disabled="readonly">
            <el-option
              v-for="item in dataScopeDictDatas"
              :key="parseInt(item.value)"
              :label="item.label"
              :disabled="item.disabled"
              :value="parseInt(item.value)"
            ></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="form.status" :disabled="readonly">
            <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
                      :key="dict.value" :label="parseInt(dict.value)">{{ dict.label }}
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item
          v-show="this.form.dataScope == dataScopeEnum.CUSTOM || this.form.dataScope == dataScopeEnum.CUSTOM_CONTAIN_CHILD">
          <span slot="label">
                <el-tooltip content="" placement="top">
                   <div slot="content">
                     父子联动：(选中父节点，自动选择子节点),注：半选中状态不会保存
                   </div>
                  <i class="el-icon-question"/>
                </el-tooltip>
                数据权限
              </span>
          <el-checkbox :checked="form.dataCheckStrictly" @change="handleCheckedTreeConnect($event, 'tree')"
                       :disabled="readonly">
            父子联动
          </el-checkbox>
          <el-checkbox :disabled="readonly" v-model="dataExpand" @change="handleCheckedTreeExpand($event, 'tree')">
            展开/折叠
          </el-checkbox>
          <el-checkbox :disabled="readonly" v-model="dataNodeAll" @change="handleCheckedTreeNodeAll($event, 'tree')">
            全选/全不选
          </el-checkbox>
          <el-tree class="tree-border"
                   :data="dataOptions"
                   v-if="refreshTree"
                   :disabled="readonly"
                   show-checkbox
                   default-expand-all
                   ref="tree"
                   node-key="id"
                   :check-strictly="treeCheckStrictly"
                   empty-text="加载中，请稍后" :props="defaultProps"></el-tree>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer" v-if="!readonly">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
      <div slot="footer" class="dialog-footer" v-if="readonly">
        <el-button @click="cancel">关 闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  createDataPermissionConfig,
  updateDataPermissionConfig,
  deleteDataPermissionConfig,
  getDataPermissionConfig,
  getDataPermissionConfigPage,
  exportDataPermissionConfigExcel, createDataPermissionConfigExclude, deleteDataPermissionConfigExclude
} from "@/api/sa/dataPermissionConfig";
import {
  getDataPermissionItemPage
} from "@/api/sa/dataPermissionItem";
import {
  getDataPermissionDefineData
} from "@/api/sa/dataPermissionDefine.js";
import {
  getDataPermissionDefineAllList
} from "@/api/sa/dataPermissionDefine";
import Editor from '@/components/Editor';
import SaOrgTree from '@/components/SaOrgTree';
import {COMMON_TREE, CommonStatusEnum, OrgKindEnum, SaDataScopeEnum, SaLikeOrIn} from "@/utils/constants";
import {DICT_TYPE, getDictDatas} from "@/utils/dict";
import {generateFullId} from "@/utils/ruoyi";

export default {
  name: "DataPermissionConfig",
  components: {
    Editor, SaOrgTree
  },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 导出遮罩层
      exportLoading: false,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 数据权限配置列表
      list: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      readonly: false,
      // 查询参数
      queryParams: {
        pageNo: 1,
        pageSize: 10,
        orgFullId: null,
        orgFullName: null,
        permissionItemId: null,
        dataScope: null,
        status: null,
        version: null,
        createTime: [],
        dataContent: null,
      },
      // 表单参数
      form: {
        dataCheckStrictly: false,
      },
      // 表单校验
      rules: {
        dataScope: [
          {required: true, message: "权限范围不能为空", trigger: "blur"}
        ],
        status: [
          {required: true, message: "权限范围不能为空", trigger: "blur"}
        ],
        likeOrIn: [
          {required: true, message: "权限范围不能为空", trigger: "blur"}
        ]
      },
      defineList: [],
      cureentDefineId: null,
      queryItemCode: null,
      // 权限项查询参数
      itemQueryParams: {
        pageNo: 1,
        pageSize: 10,
        code: null,
        defineId: null
      },
      currentOrgTreeData: null,
      defineDataMap: {},
      currentItemData: null,
      itemList: [],
      itemTotal: 0,
      dataExpand: false,
      dataNodeAll: false,

      dataOptions: [],
      defaultProps: {
        label: "name",
        children: "children"
      },
      treeCheckStrictly: true,
      dataScopeEnum: SaDataScopeEnum,
      dataScopeDictDatas: getDictDatas(DICT_TYPE.SA_DATA_SCOPE),
      // 权限基础数据缓存;
      dataContent: {},
      refreshTree: true
    };
  },
  created() {
    this.getDefineList();
    this.getList();
  },
  methods: {

    orgTreeNodeClick(node) {
      this.currentOrgTreeData = node
      if (node.code == OrgKindEnum.Root.code) {
        this.currentOrgTreeData = undefined
      }
      this.getList()
    },
    /** 查询列表 */
    getList() {
      if (!this.currentOrgTreeData || !this.currentItemData) {
        return
      }
      this.loading = true;
      this.queryParams.orgFullId = this.currentOrgTreeData.fullId
      this.queryParams.permissionItemId = this.currentItemData.id
      // 执行查询
      getDataPermissionConfigPage(this.queryParams).then(response => {
        this.list = response.data.list;
        this.list.forEach(row => {
          row.status = !!row.excludeId ? CommonStatusEnum.DISABLE : row.status
        })
        this.total = response.data.total;
        this.loading = false;
      }).finally(() => {
        this.loading = false;
      });
    },
    getDefineList() {
      getDataPermissionDefineAllList().then(response => {
        if (response.data && response.data.length > 0) {
          response.data.forEach(item => {
            this.defineDataMap[item.id] = item
          })
          this.cureentDefineId = response.data[0].id
          this.defineList = response.data;
          this.itemQueryParams.defineId = this.cureentDefineId
          this.getItemList();
          this.getDefineData()
          this.refreshDataScopeOptions()
        }
      }).finally(() => {
        this.loading = false;
      })
    },
    getItemList() {
      this.loading = true
      getDataPermissionItemPage(this.itemQueryParams).then(response => {
        this.itemList = response.data.list;
        this.itemTotal = response.data.total;
        this.loading = false;
      })
    },
    // 查询权限基础数据
    getDefineData() {
      if (!this.dataContent[this.cureentDefineId]) {
        getDataPermissionDefineData(this.itemQueryParams.defineId).then(response => {
          this.dataContent[this.itemQueryParams.defineId] = response.data
        })
      }
    },
    handDefineChange(val) {
      this.itemQueryParams.pageNo = 1
      this.cureentDefineId = val
      this.getItemList()
      this.getDefineData()
      this.refreshDataScopeOptions()
    },

    refreshDataScopeOptions() {
      let d = getDictDatas(DICT_TYPE.SA_DATA_SCOPE);
      this.dataScopeDictDatas = []
      d.forEach(item => {
        if (item.status == CommonStatusEnum.ENABLE) {
          if (this.defineDataMap[this.cureentDefineId].tableName != 'sa_oporg') {
            if (item.value == 4 || item.value == 5) {
              item.disabled = true
            }
          } else {
            delete item.disabled
          }
          this.dataScopeDictDatas.push(item)
        }
      })
    },

    handleQueryItemList() {
      this.itemQueryParams.pageNo = 1
      this.getItemList()
    },
    //选择 权限项
    handleItemChange(val) {
      this.currentItemData = val
      this.getList()
    },
    /** 取消按钮 */
    cancel() {
      this.open = false;
      this.readonly = false
      this.reset();
    },
    /** 表单重置 */
    reset() {
      this.form = {
        id: undefined,
        orgFullId: undefined,
        orgFullName: undefined,
        permissionItemId: undefined,
        dataScope: undefined,
        dataCheckStrictly: false,
        likeOrIn: undefined,
        status: undefined,
        version: undefined,
        dataContent: undefined,
      };
      this.dataCheckStrictly = true
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNo = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    initDefineData() {
      let currentDefineData = this.defineDataMap[this.cureentDefineId]
      if (!!currentDefineData.parentIdKeyName) {
        //设置了父节点
        this.dataOptions = []
        let root = {id: currentDefineData.rootId || '0'}
        let data = this.dataContent[currentDefineData.id] || []
        data = this.handleTree(data, undefined, undefined, undefined, root.id)
        data = generateFullId(data)
        this.dataOptions.push(...data);
      }else{
        this.dataOptions = []
        let data = this.dataContent[currentDefineData.id] || []
        this.dataOptions.push(...data);
      }

    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      if (!this.currentOrgTreeData) {
        this.$modal.msgWarning("请选择下机构");
        return
      }
      if (!this.currentItemData) {
        this.$modal.msgWarning("请选择权限项类型");
        return
      }

      this.initDefineData()

      this.form.orgFullName = this.currentOrgTreeData.fullName
      this.form.orgFullId = this.currentOrgTreeData.fullId
      this.form.status = CommonStatusEnum.ENABLE
      this.form.permissionItemCode = this.currentItemData.code
      this.form.permissionItemId = this.currentItemData.id
      this.form.dataCheckStrictly = false
      this.dataCheckStrictly = true
      this.open = true;
      this.title = "添加数据权限配置";
      this.handleRefreshTree()
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      this.initDefineData()
      const id = row.id;
      this.open = true;
      this.title = "修改数据权限配置";
      getDataPermissionConfig(id).then(response => {
        this.form = response.data;
        this.form.dataCheckStrictly = false
        this.dataCheckStrictly = true
        this.form.permissionItemCode = this.currentItemData.code
        this.form.likeOrIn = response.data.likeOrIn
        if (!!response.data.dataContent) {
          let checkedNodes = response.data.dataContent.split(',')
          setTimeout(() => {
            if (this.form.dataScope == this.dataScopeEnum.CUSTOM) {
              this.$refs.tree.setCheckedKeys(!!checkedNodes ? checkedNodes : []);
            } else if (this.form.dataScope == this.dataScopeEnum.CUSTOM_CONTAIN_CHILD) {
              let checkedKeys = []
              checkedNodes.forEach(item => {
                checkedKeys.push(item.substring(item.lastIndexOf("/") + 1, item.length))
              })
              this.$refs.tree.setCheckedKeys(!!checkedKeys ? checkedKeys : []);
            }
          })
        }
      });
    },
    handleReadonly(row) {
      this.readonly = true
      this.handleUpdate(row)
      this.title = "查看数据权限配置";
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (!valid) {
          return;
        }
        this.form.dataContent = ''
        if (this.form.dataScope == this.dataScopeEnum.CUSTOM) {
          // 使用权限时，如果使用in生成脚本，则必须包含半选状态；若使用全路径like的话，则不能包含半选状态。当前暂时使用IN。
          this.form.dataContent = [...this.$refs.tree.getCheckedKeys(), ...this.$refs.tree.getHalfCheckedKeys()].join(",")
        } else if (this.form.dataScope == this.dataScopeEnum.CUSTOM_CONTAIN_CHILD) {
          let chooseData = this.$refs.tree.getCheckedNodes();
          let effectiveMap = {}
          let effectiveData = []
          chooseData.forEach(item => {
            let canAdd = true
            for (let key in effectiveMap) {
              let effective = effectiveMap[key]
              if (effective.fullId.indexOf(item.fullId) > -1) {
                delete effectiveMap[effective.id]
              }
              if (item.fullId.indexOf(effective.fullId) > -1) {
                canAdd = false
              }
            }
            if (canAdd) {
              effectiveData.push(item)
              effectiveMap[item.id] = item
            }
          })
          let newEffectiveData = []
          for (let key in effectiveMap) {
            newEffectiveData.push(effectiveMap[key].fullId)
          }
          this.form.dataContent = newEffectiveData.join(",")
        }
        // 修改的提交
        if (this.form.id != null) {
          updateDataPermissionConfig(this.form).then(response => {
            this.$modal.msgSuccess("修改成功");
            this.open = false;
            this.getList();
          });
          return;
        }
        // 添加的提交
        createDataPermissionConfig(this.form).then(response => {
          this.$modal.msgSuccess("新增成功");
          this.open = false;
          this.getList();
        });
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const id = row.id;
      this.$modal.confirm('是否确认删除数据权限配置编号为"' + id + '"的数据项?').then(function () {
        return deleteDataPermissionConfig(id);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {
      });
    },

    handleCreateExclude(row) {
      const id = row.id;
      const fullId = this.currentOrgTreeData.fullId
      this.$modal.confirm('确认排除从 "' + row.orgFullName + '" 继承的数据权限吗?').then(function () {
        return createDataPermissionConfigExclude({orgFullId: fullId, permissionConfigId: row.id});
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("排除成功");
      }).catch(() => {
      });
    },

    handleDeleteExclude(row) {
      const excludeId = row.excludeId
      this.$modal.confirm('确认不再排除从 "' + row.orgFullName + '" 继承的数据权限吗?').then(function () {
        return deleteDataPermissionConfigExclude(excludeId);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("操作成功");
      }).catch(() => {
      });
    },

    handleRefreshTree() {
      this.refreshTree = false;
      this.$nextTick(() => {
        this.refreshTree = true;
      });
    },
    handleCheckedTreeConnect(value, type) {
      this.treeCheckStrictly = !value;
      this.handleRefreshTree()
    },
    handleCheckedTreeExpand(value, type) {
      let treeList = this.dataOptions;
      for (let i = 0; i < treeList.length; i++) {
        this.$refs.tree.store.nodesMap[treeList[i].id].expanded = value;
      }
    },
    handleCheckedTreeNodeAll(value, type) {
      this.$refs.tree.setCheckedNodes(value ? this.dataOptions : []);
    }
  }
};
</script>
